package com.car.loan.project.xr.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.car.loan.common.exception.loan.LoanParameterException;
import com.car.loan.common.utils.StringUtils;
import com.car.loan.common.utils.file.PdfUtil;
import com.car.loan.framework.aspectj.lang.annotation.DataStatus;
import com.car.loan.framework.aspectj.lang.annotation.Log;
import com.car.loan.framework.aspectj.lang.enums.BusinessType;
import com.car.loan.framework.web.domain.AjaxResult;
import com.car.loan.project.cm.domain.CmBank;
import com.car.loan.project.cm.mapper.CmBankMapper;
import com.car.loan.project.system.domain.SysUser;
import com.car.loan.project.xr.domain.LoanDetail;
import com.car.loan.project.xr.domain.LoanExt;
import com.car.loan.project.xr.domain.LoanStatus;
import com.car.loan.project.xr.mapper.LoanDetailMapper;
import com.car.loan.project.xr.mapper.LoanExtMapper;
import com.car.loan.project.xr.service.ILoanService;
import com.car.loan.project.xr.service.ILoanStatusService;
import com.car.loan.project.xr.service.loan.payment.LoanPaymentService;
import com.car.loan.project.xr.util.RedisDataUtil;
import com.car.loan.project.xr.util.bo.business.LoanBaseInfo;
import com.car.loan.project.xr.util.bo.business.payment.PaymentInfoBo;
import com.car.loan.project.xr.util.enums.LicenseInfoStatus;
import com.car.loan.project.xr.util.enums.MakeLoansInfoStatus;
import com.car.loan.project.xr.util.enums.MortgageInfoStatus;
import com.car.loan.project.xr.util.enums.PaymentInfoStatus;
import com.car.loan.project.xr.util.enums.PaymentSettleAccountsStatus;
import com.car.loan.project.xr.util.select.LoanBasePageParam;
import com.car.loan.project.xr.util.vo.PaymentApplyVo;
import com.car.loan.project.xr.util.vo.pdf.SettlementPdf;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.itextpdf.text.DocumentException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author huangding
 * @description
 * @date 2019/11/26 17:05
 */
@RestController
@RequestMapping("xr/payment/info")
@Api(value = "付款信息", tags = "车贷业务-付款信息填写")
public class LoanPaymentInfoController {


    @Autowired
    private LoanPaymentService loanPaymentService;

    @Autowired
    private ILoanService loanService;

    @Autowired
    private ILoanStatusService loanStatusService;

    @Resource
    private RedisDataUtil redisDataUtil;


    @PreAuthorize("@ss.hasPermi('payment:info:list')")
    @GetMapping("list")
    @ApiOperation(value = "获取付款信息列表", response = LoanBaseInfo.class, responseContainer = "list")
    @DataStatus(loanStatusEnum = com.car.loan.common.enums.LoanStatusEnum.PAYMENT_INFO_STATUS)
    public AjaxResult applyList(@Valid LoanBasePageParam loanBasePageParam) {
        return AjaxResult.success(loanService.page(loanBasePageParam));
    }


    @PreAuthorize("@ss.hasPermi('payment:info:query')")
    @GetMapping("{loanId}")
    @ApiOperation(value = "获取付款信息详情", response = PaymentApplyVo.class)
    public AjaxResult saveApply(@PathVariable Long loanId) {
        return loanPaymentService.info(loanId);
    }


    @GetMapping("pdf/{loanId}")
    @ApiOperation(value = "获取PDF打印信息", response = PdfInfo.class)
    public AjaxResult getPdfInfo(@PathVariable Long loanId) {
        Optional<LoanStatus> optionalLoanStatus = loanStatusService.getByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));
        Map<String, SysUser> redisUserMap = redisDataUtil.getRedisUserMap();
        PdfInfo pdfInfo = new PdfInfo();
        pdfInfo.setBusinessTime(loanStatus.getBusinessTime());
        SysUser sysUserBusiness = redisUserMap.get(loanStatus.getBusinessAdminId().toString());
        if (null != sysUserBusiness) {
            pdfInfo.setBusinessName(sysUserBusiness.getUserName());
        }
        pdfInfo.setBusinessAuditTime(loanStatus.getBusinessAuditTime());
        SysUser sysUserBusinessAudit = redisUserMap.get(loanStatus.getBusinessAuditId().toString());
        if (null != sysUserBusinessAudit) {
            pdfInfo.setBusinessAuditName(sysUserBusinessAudit.getUserName());
        }
        if (null != loanStatus.getBusinessApostilleId()) {
            pdfInfo.setBusinessApostilleTime(loanStatus.getBusinessApostilleTime());
            SysUser sysUserBusinessApostille = redisUserMap
                .get(loanStatus.getBusinessApostilleId().toString());
            if (null != sysUserBusinessApostille) {
                pdfInfo.setBusinessApostilleName(sysUserBusinessApostille.getUserName());
            }
        }
        pdfInfo.setPaymentAuditTime(loanStatus.getPaymentAuditTime());
        SysUser sysUserPaymentAudit = redisUserMap.get(loanStatus.getPaymentAuditId().toString());
        if (null != sysUserPaymentAudit) {
            pdfInfo.setPaymentAuditName(sysUserPaymentAudit.getUserName());
        }
        return AjaxResult.success(pdfInfo);
    }

    @Data
    public static class PdfInfo {

        @ApiModelProperty("业务提交时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime businessTime;

        private String businessName;

        @ApiModelProperty("业务审核时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime businessAuditTime;

        private String businessAuditName;

        /**
         * $column.columnComment
         */
        @ApiModelProperty("加签审核时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime businessApostilleTime;

        private String businessApostilleName;

        @ApiModelProperty("付款审核时间")
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime paymentAuditTime;

        private String paymentAuditName;

    }


    @PreAuthorize("@ss.hasPermi('payment:info:add')")
    @PostMapping("infoWrite")
    @Log(title = "付款信息填写", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "付款信息填写", notes = "需打印付款审批单")
    public AjaxResult saveApply(@RequestBody @Valid PaymentInfoBo paymentInfoBo) {
        return loanPaymentService.paymentInfoWrite(paymentInfoBo);
    }


    @PreAuthorize("@ss.hasPermi('payment:info:withdraw')")
    @PutMapping("withdraw/{loanId}")
    @Log(title = "撤回付款付款信息填写", businessType = BusinessType.WITHDRAW)
    @ApiOperation(value = "撤回付款付款信息填写", notes = "结算信息填写后不可撤回")
    public AjaxResult withdrawApply(@PathVariable Long loanId) {
        Optional<LoanStatus> optionalLoanStatus = loanStatusService.getByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("业务状态数据异常请联系管理员"));
        if (PaymentSettleAccountsStatus.SUBMIT.status == loanStatus.getSettleAccountsStatus()) {
            return AjaxResult.error("结算信息已填写，不可撤回");
        }
        loanStatus.setPaymentInfoStatus((long) PaymentInfoStatus.INIT.status);
        loanStatusService.updateLoanStatus(loanStatus);
        return AjaxResult.success();
    }

}
